//=============================================================================
//
// MODULE      : GCD
// DESCRIPTION : Greatest Common Divisor routines.
//
// LANGUAGE    : "Cpp"
// VERSION     : 1.00
// DATE        : 25/08/2009
// WRITTEN BY  : CRMA
// CHANGES     : description and reason of the change.
//               change date
//               Modified by:
//
//
//=============================================================================

#include "gcd.h"


// Subtraction based algorithm.

unsigned long GCDSubBased::gcd(unsigned long a, unsigned long b) {
	_iter = 0;
	if (0 == a) {
		_iter = 1;
		return (b);
	}
	while (b != 0) {
		if (a > b) {
			a = a - b;
		} else {
			b = b - a;
		}
		_iter++;
	}
	return (a);
}
Factory<GCDBase,GCDSubBased> GCDSubBased::myFactory;


// Division based algorithm.
unsigned long GCDDivBased::gcd(unsigned long a, unsigned long b) {
	unsigned int t;
	_iter = 0;
	while (b != 0) {
		t = b;
		b = a % b;
		a = t;
		_iter++;
	}
	return a;
}
Factory<GCDBase,GCDDivBased> GCDDivBased::myFactory;


// Recursive version algorithm
unsigned long GCDRecursive::gcd(unsigned long a, unsigned long b) {
	_iter++;		// wrong we need a constuctor
	if (0 == b) {
		return (a);
	} else {
		return (gcd(b, a % b));
	}
}

Factory<GCDBase,GCDRecursive> GCDRecursive::myFactory;

////////////////////////////////////////////////////////////////////


// Some method that might need to create an instance
GCDBase *someMethod (std::map<int,GCDBase::GcdBaseClassFactory *> factories, int type)
{
  return factories[type]->createInstance();
}

int main()
{
	GCDBase                                         *simpleInstance     = NULL;
	std::map<int,GCDBase::GcdBaseClassFactory *>  factories;

  factories[1] = &GCDSubBased::myFactory;
  factories[2] = &GCDDivBased::myFactory;
  factories[3] = &GCDRecursive::myFactory;

  simpleInstance = someMethod (factories,1);
  if (simpleInstance)
  {
    simpleInstance->gcd(1234, 4);
    std::cout << simpleInstance->iterations() << std::endl;
    delete simpleInstance;
  }
  else
  {
    std::cout << "Instance creation failed" << std::endl;
  }

  simpleInstance = someMethod (factories,2);
  if (simpleInstance)
  {
    simpleInstance->gcd(1234, 4);
    std::cout << simpleInstance->iterations() << std::endl;
    delete simpleInstance;
  }
  else
  {
    std::cout << "Instance creation failed" << std::endl;
  }

  return 0;
}



// EOF

